package convertTestsToJUnit;


import java.io.IOException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.ArrayList;


import executor.ReflectionExecutor;
import ga.GAInfo;
import ga.Individual;

import instrumentation.BlockClass;
import instrumentation.TrackerCoverage;


import ReadWGZ.ReadFilewgzMDR;


import model.CUT;
import model.TestClusterBuilder;
import operations.Operation;
import util.GAConfig;
import util.Randomness;

public class TestUnitTestGenMain {
	public static void main(String[] args)throws  IOException, ClassNotFoundException {
		TrackerCoverage tracker=  TrackerCoverage.getTracker();

		ReadFilewgzMDR readFileWGZ = new ReadFilewgzMDR();


	       GAInfo     gaInfo     = new GAInfo();
			long startTime = Calendar.getInstance().getTimeInMillis();
			gaInfo.setTestTimeOut(60 * 500);
			 gaInfo.setTestTimeOut( 60 * 1000*10); ;
				gaInfo.setStartTime(startTime);


		Randomness.reset(15);
		
		 Set<Class<?>> allClasses = new LinkedHashSet<Class<?>>();
	      //get class from file
	      allClasses.addAll(TestClusterBuilder.readClassFromFile());

	      
	      TestClusterBuilder TestCluster = new TestClusterBuilder(allClasses);
	      List<TestClusterBuilder> tcluster=new LinkedList<TestClusterBuilder>();
	      tcluster.add(TestCluster);
			 Map<String, BlockClass> blockClasses=readFileWGZ.readFileWGZ(tcluster);
			 Map<String,Set<Integer>> classBranches=readFileWGZ.getClazzCondition(blockClasses);
				gaInfo.setMapBlockClasses(blockClasses);
				gaInfo.setClazzBranches(classBranches);

	      gaInfo.setTestCluster(TestCluster);
	      CUT cut = TestCluster.getCut();
	      gaInfo.setClzToTest(cut.getClazz());
		  List<Operation> initialConstructors= Operation.randomGenerateInitialConstructors(TestCluster);
	      List<Operation> ops=new LinkedList<Operation>();
    	  ops.addAll(Operation.randomlyGenerateOperation(TestCluster,50));
	      Individual individual1=new Individual(initialConstructors,ops);
	      
	//      ReflectionExecutor.execute(gaInfo,individual1);
				
	
			//	System.out.println("1)\n" + individual1.toString());
			
				Map<Integer,Individual> branchCoveredByIndividual = new HashMap<Integer, Individual>() ;
				
				 branchCoveredByIndividual.put(1, individual1);
					ReflectionExecutor.execute(gaInfo,individual1);
					tracker.calculateFitness(individual1,gaInfo.getClazzBranches(cut.getClazz().getName()) );
					System.out.println(tracker.toString());
					gaInfo.setTracker(tracker);

					Map<Integer, Individual> suiteBR = new HashMap<Integer, Individual>(tracker.getBranchCoveredByIndividual());
					Map<String, Individual> noDuplicatesuiteBR = new HashMap<String, Individual>();
					List<Individual> arryList=new ArrayList<Individual>();

					for (Integer i : suiteBR.keySet()){
						if(noDuplicatesuiteBR.containsKey(suiteBR.get(i).toString())) continue;
						noDuplicatesuiteBR.put(suiteBR.get(i).toString(), suiteBR.get(i));
						arryList.add(suiteBR.get(i));
					}
					Individual[] suiteBRToArray = new Individual[arryList.size()];
					
					suiteBRToArray = arryList.toArray(suiteBRToArray);
					Arrays.sort(suiteBRToArray);
					
					Map<Integer, Individual> reducedSuiteBR = new HashMap<Integer, Individual>();
					gaInfo.setTestTimeOut(6000000);
					suiteBR.putAll(branchCoveredByIndividual);
					final TestSuiteReducer reducer = new TestSuiteReducer(gaInfo);
					for (Individual i : suiteBRToArray)
						reducedSuiteBR.putAll(reducer.process(i,reducedSuiteBR));
					JUnitTestGenerator gen = new JUnitTestGenerator(GAConfig
							.getDirGeneratedTests(), gaInfo, reducedSuiteBR, "Test",1);
					gen.writeSuite();
					gaInfo.setTestTimeOut(0);
//				ReflectionExecutor.execute(gaInfo,offspring[0]);
//				ReflectionExecutor.execute(gaInfo,offspring[1]);
				System.exit(0);

	}

}
